home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ETO Development Tools 4
/
ETO Development Tools 4.iso
/
Tools - Objects
/
MacApp
/
MacApp 3.0a2
/
Libraries
/
UMacAppGlobals.cp
< prev
next >
Wrap
Text File
|
1991-05-01
|
21KB
|
906 lines
// UMacAppGlobals.cp
// Copyright © 1984-1991 by Apple Computer Inc. All rights reserved.
#include "UMacAppGlobals.h"
#ifndef __ULIST__
#include <UList.h>
#endif
#ifndef __APPLEEVENTS__
#include <AppleEvents.h>
#endif
#ifndef __EDITIONS__
#include <Editions.h>
#endif
#ifndef __UAPPLEEVENTS__
#include <UAppleEvents.h>
#endif
#ifndef __UEVENT__
#include <UEvent.h>
#endif
#ifndef __UCOMMAND__
#include <UCommand.h>
#endif
#ifndef __UDESIGNATOR__
#include <UDesignator.h>
#endif
#ifndef __UEVTHANDLER__
#include <UEvtHandler.h>
#endif
#ifndef __UAPPLICATION__
#include <UApplication.h>
#endif
#ifndef __UDOCUMENT__
#include <UDocument.h>
#endif
#ifndef __UFILEBASEDDOCUMENT__
#include <UFileBasedDocument.h>
#endif
#ifndef __UPRINTHANDLER__
#include <UPrintHandler.h>
#endif
#ifndef __BALLOONS__
#include <Balloons.h>
#endif
#ifndef __UVIEW__
#include <UView.h>
#endif
#ifndef __UADORNERS__
#include <UAdorners.h>
#endif
#ifndef __UWINDOW__
#include <UWindow.h>
#endif
#ifndef __CONTROLS__
#include <Controls.h>
#endif
#ifndef __UCONTROL__
#include <UControl.h>
#endif
#ifndef __USCROLLER__
#include <UScroller.h>
#endif
#ifndef __UMACAPPUTILITIES__
#include <UMacAppUtilities.h>
#endif
#ifndef __UERRORMGR__
#include <UErrorMgr.h>
#endif
#ifndef __UMEMORY__
#include <UMemory.h>
#endif
#ifndef __ERRORS__
#include <Errors.h>
#endif
#ifndef __TOOLUTILS__
#include <ToolUtils.h>
#endif
#ifndef __UBUSYCURSOR__
#include <UBusyCursor.h>
#endif
#ifndef __UDEBUG__
#include <UDebug.h>
#endif
#ifndef __UINSPECTOR__
#include <UInspector.h>
#endif
#ifndef __UDEPENDENCIES__
#include <UDependencies.h>
#endif
#ifndef __MENUS__
#include <Menus.h>
#endif
#ifndef __UMENUMGR__
#include <UMenuMgr.h>
#endif
#ifndef __SCRAP__
#include <Scrap.h>
#endif
#ifndef __UCLIPBOARDMGR__
#include <UClipboardMgr.h>
#endif
#ifndef __UDESKSCRAPVIEW__
#include <UDeskScrapView.h>
#endif
#ifndef __USYNCHSCROLLER__
#include <USynchScroller.h>
#endif
#ifndef __RESOURCES__
#include <Resources.h>
#endif
#ifndef __FONTS__
#include <Fonts.h>
#endif
#ifndef __PACKAGES__
#include <Packages.h>
#endif
#ifndef __SCRIPT__
#include <Script.h>
#endif
#ifndef __DEVICES__
#include <Devices.h>
#endif
#ifndef __STDIO__
#include <StdIO.h>
#endif
//--------------------------------------------------------------------------------------------------
TextStyle gApplicationStyle;
Boolean gCouldPrint;
#if qExperimentalAndUnsupported
Boolean gEnableDoubleBuffering = TRUE;
#endif
Boolean gOldChooserFlag;
TDynamicArray* gSignatures;
TextStyle gSystemStyle;
WindowPtr gWorkPort;
RgnHandle gTempRgn;
RgnHandle gTempRgn2;
#if qDebug
Boolean gBusyTempRgn = FALSE;
Str255 gUsedBy = "";
Boolean gBusyTempRgn2 = FALSE;
Str255 gUsedBy2 = "";
#endif
StringHandle pCopyright;
TrapPatch pETSPatch;
FailInfo pFi;
//--------------------------------------------------------------------------------------------------
#pragma segment MAGlobalsRes
// Retrieve the title of the button control. If itemNo isn't a button, then return ''.
pascal void GetAlertButtonTitle(DialogPtr theDialog, short itemNo, Str255& theTitle)
{
short itemType;
Handle item;
Rect box;
theTitle = "";
GetDItem(theDialog, itemNo, itemType, item, box);
if (itemType == (ctrlItem + btnCtrl))
GetCTitle((ControlHandle)item, theTitle);
}
//--------------------------------------------------------------------------------------------------
#pragma segment MAGlobalsRes
// Handle a keypress that has been mapped to one of the button controls.
pascal void DoAlertKeyDown(DialogPtr theDialog, short itemNo)
{
short itemType;
Handle item;
Rect box;
long finalTicks;
GetDItem(theDialog, itemNo, itemType, item, box);
if (itemType == (ctrlItem + btnCtrl))
{
// this code gives visual feedback
HiliteControl((ControlHandle)item, inButton); // hilite the button
Delay(8, finalTicks); // delay for 8 ticks
HiliteControl((ControlHandle)item, 0); // stop hiliting the button
}
}
//--------------------------------------------------------------------------------------------------
#pragma segment MAGlobalsRes
pascal Boolean CompareAlertKeysToItem(DialogPtr theDialog, Str31& theChars, short& itemHit)
// Compares the buffered multi-byte chars to the first character of each button title
// 1st button in alert (by convention == "OK"). 2nd button in alert
// (by convention == "Cancel"). 3rd button in alert (by convention == "No")
{
Str255 title;
GetAlertButtonTitle(theDialog, ok, title);
if (CompareMultiByteChars(theChars, title, FALSE))
{
itemHit = ok;
return TRUE;
}
GetAlertButtonTitle(theDialog, cancel, title);
if (CompareMultiByteChars(theChars, title, FALSE))
{
itemHit = cancel;
return TRUE;
}
GetAlertButtonTitle(theDialog, kNoButton, title);
if (CompareMultiByteChars(theChars, title, FALSE))
{
itemHit = kNoButton;
return TRUE;
}
return FALSE;
}
//--------------------------------------------------------------------------------------------------
#pragma segment MAGlobalsRes
pascal Boolean MacAppAlertFilter(DialogPtr theDialog,
EventRecord& theEvent,
short& itemHit)
{
if (gApplication)
return gApplication->AlertFilter(theDialog, theEvent, itemHit);
else
return FALSE; //???
}
//--------------------------------------------------------------------------------------------------
#pragma segment MAGlobalsRes
pascal void ApplicationBeep(void)
{
if (gApplication)
gApplication->Beep(2);
else
SysBeep(2);
}
//--------------------------------------------------------------------------------------------------
#pragma segment MAGlobalsRes
/*$Push*/
#if qTrace
/*$D+*/
#endif
pascal void CleanupMacApp(void)
{
long OldA5 = SetCurrentA5(); // ***** Called from trap patches *****
SetResLoad(TRUE); // Make sure segments can load
UnpatchTrap(pETSPatch); // Guaranteed not to fail
if (gApplication)
gApplication->Terminate();
gBusyCursor = (TBusyCursor *)FreeIfObject(gBusyCursor);
if (qNeedsAppleEventMgr || gConfiguration.hasAppleEventMgr)
AEDisposeDesc(gServerAddress);
#if qDebug
DebugTerminate();
#endif
UnpatchAll();
SetChooserAlert(gOldChooserFlag);
SetA5(OldA5);
}
//$Pop
//--------------------------------------------------------------------------------------------------
#if qDebug
#pragma segment MADebug
/*$Push*/
#if qTrace
/*$D+*/
#endif
pascal void DoneWithTempRgn(void)
/* Indicates that gTempRgn is no longer in use. Call this only if qDebug
is true. */
{
if (!gBusyTempRgn)
ProgramBreak("DoneWithTempRgn called, but gTempRgn is not locked");
gBusyTempRgn = FALSE;
gUsedBy = "";
SetEmptyRgn(gTempRgn);
}
//$Pop
#endif
//--------------------------------------------------------------------------------------------------
#if qDebug
#pragma segment MADebug
/*$Push*/
#if qTrace
/*$D+*/
#endif
pascal void DoneWithTempRgn2(void)
/* Indicates that gTempRgn2 is no longer in use. Call this only if qDebug
is true. */
{
if (!gBusyTempRgn2)
ProgramBreak("DoneWithTempRgn2 called, but gTempRgn2 is not locked");
gBusyTempRgn2 = FALSE;
gUsedBy2 = "";
SetEmptyRgn(gTempRgn2);
}
//$Pop
#endif
//--------------------------------------------------------------------------------------------------
#if qDebug
#pragma segment MADebug
pascal void EntDebugger(Boolean entering)
{
if (gBusyCursor)
gBusyCursor->Activate(!entering);
}
#endif
//--------------------------------------------------------------------------------------------------
#pragma segment MADebug
pascal long LookupSymbol(Str255& sym)
{
if (gInitialized)
return (gApplication->GetTarget())->LookupSymbol(sym);
else
return -1;
}
//--------------------------------------------------------------------------------------------------
#pragma segment MATerminate
pascal void ExitMacApp(void)
{
CleanupMacApp();
ExitToShell();
}
//--------------------------------------------------------------------------------------------------
#pragma segment MAGlobalsRes
pascal WindowPtr FreeIfWMgrWindow(WindowPtr w,
Boolean dispose)
{
if (w)
{
if (dispose)
{
if (w == qd.thePort) /* Only need to invalidate focus if freed
window is the current port */
{
if (gApplication)
gApplication->InvalidateFocus();
SetPort(gWorkPort);
}
DisposeWindow(w);
}
else
CloseWindow(w);
}
return NULL; // convenience to caller
}
//--------------------------------------------------------------------------------------------------
#pragma segment MAGlobalsRes
pascal DialogPtr GetNewCenteredDialog(short dialogID,
Ptr dStorage,
WindowPtr behind)
{
DialogTHndl dlogTemplate;
SetCursor(qd.arrow);
if (gApplication)
gApplication->InvalidateMouseRegions();
dlogTemplate = (DialogTHndl)GetResource('DLOG', dialogID);
if (dlogTemplate)
{
CenterRectOnScreen((*dlogTemplate)->boundsRect, TRUE, TRUE, TRUE);
return GetNewDialog(dialogID, dStorage, behind);
}
else
{
SysBeep(2); // At least give some indication
#if qDebug
Str255 theString;
ConcatNumber("Unable to find ‘DLOG’ resource ", dialogID, theString);
ProgramBreak(theString);
#endif
}
return NULL;
}
//--------------------------------------------------------------------------------------------------
// Really a utility but, the gWorkPort isn't reachable from UMacAppUtilities
#pragma segment MAUtilitiesRes
pascal void GetTextStyleFontInfo(const TextStyle& theTextStyle,
FontInfo& theFontInfo,
short& theFontHeight)
{
GrafPtr savedPort;
GetPort(savedPort);
SetPort(gWorkPort);
SetPortTextStyle(theTextStyle);
theFontHeight = MAGetFontInfo(theFontInfo);
SetPort(savedPort);
}
//--------------------------------------------------------------------------------------------------
// Must be in the init segment; unloaded at start of event loop
#pragma segment MAInit
pascal void DoInitUMacApp(void)
{
// Initialize runtime support for objects
InitUObject();
#if qDebug
InitUDebug(NULL, NULL, (Ptr) & EntDebugger, (Ptr) & LookupSymbol);
#endif
#if qInspector
InitUInspector();
#endif
#if qDebug
gTraceSetupMenus = FALSE;
#endif
gOrthogonal[vSel] = hSel;
gOrthogonal[hSel] = vSel;
gPrinting = FALSE;
gCurrPrintHandler = NULL;
gDrawingPictScrap = FALSE;
gDrawingPictScrapView = NULL;
gNumUntitled = 1; // call the first document Untitled-1
gErrorParm3 = "";
gFocusedView = NULL;
SetTextStyle(gSystemStyle, systemFont, normal, GetDefFontSize(), gRGBBlack);
SetTextStyle(gApplicationStyle, applFont, normal, 0, gRGBBlack);
FailOSErr(HeadPatch(pETSPatch, _ExitToShell, (Ptr) & CleanupMacApp));
pCopyright = NewString(kCopyright);
// Other 1-time initialization
gTempRgn = MakeNewRgn();
gTempRgn2 = MakeNewRgn();
gWResSignature = kNoIdentifier;
gWResType = "";
// Create a work port for our convenience
if (qNeedsColorQD || gConfiguration.hasColorQD)
gWorkPort = NewCWindow(NULL, gZeroRect, "", FALSE, documentProc, NULL, FALSE, 0);
else
gWorkPort = NewWindow(NULL, gZeroRect, "", FALSE, documentProc, NULL, FALSE, 0);
gStdHysteresis = Point(4,4); // ??? any better choice ???
{
Rect theGrayRect((*GetGrayRgn())->rgnBBox);
gStdWMoveBounds = theGrayRect;
gStdWMoveBounds.Inset(Point(4, 4));
// arbitrary minimum size; maximum size is grayRgn size minus half the title bar
gStdWSizeRect = Rect(Point(80, 80), Point(theGrayRect.Length(vSel) - 8, theGrayRect.Length(hSel)));
gStdWScreenRect = theGrayRect;
gStdWScreenRect.Inset(Point(16, 16));
}
InitUBusyCursor();
gNullPrintHandler = new TPrintHandler;
gNullPrintHandler->IPrintHandler(NULL);
gPrintHandler = gNullPrintHandler;
gOldChooserFlag = SetChooserAlert(FALSE);
// Create the signature lists.
gSignatures = new TDynamicArray;
gSignatures->IDynamicArray(kEmptyIndex, sizeof(SignatureRec));
if (qTemplateViews)
{
// ===============================================
// Suppress Linker dead stripping of these classes
if (gDeadStripSuppression)
{
DontDeadStrip(TView);
DontDeadStrip(TWindow);
DontDeadStrip(TScrollBar);
DontDeadStrip(TScrollerScrollBar);
DontDeadStrip(TScroller);
DontDeadStrip(TPrimaryScroller);
DontDeadStrip(TSecondaryScroller);
DontDeadStrip(TSynchScroller);
DontDeadStrip(TDeskScrapView);
DontDeadStrip(TFileBasedDocument);
DontDeadStrip(TNoChangesCommand);
DontDeadStrip(TList);
}
// ===============================================
RegisterStdType("TView", kStdView);
RegisterStdType("TView", kStdDefaultView);
RegisterStdType("TWindow", kStdWindow);
RegisterStdType("TScrollerScrollBar", kStdSScrollBar);
RegisterStdType("TScroller", kStdScroller);
RegisterStdType("TFileBasedDocument", kStdDocument);
RegisterStdType("TNoChangesCommand", kStdTracker);
RegisterStdType("TList", kStdList);
}
InitUAdorners(); // Temporarily needed for debug window
#if qDebug
TrcEnable(TRUE);
#endif
InitUDesignator(); // registers designator's std types
InitUMenuMgr();
InitUClipboardMgr();
InitUAppleEvents();
}
//--------------------------------------------------------------------------------------------------
#pragma segment MARes
pascal void InstallIfPrintHandler(TPrintHandler* aPrintHandler,
TView* aView)
{
TPrintHandler * aNewPrintHandler;
if ((aPrintHandler) && (aView) && (aPrintHandler != gNullPrintHandler) && (gPrintHandler != gNullPrintHandler))
{
aNewPrintHandler = (TPrintHandler *)aPrintHandler->Clone(); // signals failure if can't clone
aNewPrintHandler->fView = aView;
aNewPrintHandler->SetDefaultPrintInfo();
if (aView->fDocument)
aView->fDocument->AttachPrintHandler(aNewPrintHandler);
aView->AttachPrintHandler(aNewPrintHandler);
}
}
//--------------------------------------------------------------------------------------------------
#pragma segment MAGlobalsRes
pascal RgnHandle MakeNewRgn(void)
{
RgnHandle aRgn = NewRgn();
FailNIL(aRgn);
return aRgn;
}
//--------------------------------------------------------------------------------------------------
#pragma segment MAOpen
pascal ObjClassID DetermineClassID(IDType signature,
const MAName& className)
{
if (className.IsEmpty())
return GetClassIDFromSignature(signature);
else
return GetClassIDFromName(className);
}
//--------------------------------------------------------------------------------------------------
#pragma segment MAOpen
pascal Boolean NewStdObjectTestElement(ArrayIndex elementIndex,
void* staticLink)
{
return (((SignatureRecPtr)(gSignatures->ComputeAddress(elementIndex)))->itsSignature == *((IDType *)staticLink));
}
pascal ObjClassID GetClassIDFromSignature(IDType signature)
{
ArrayIndex i;
i = gSignatures->EachElementDoTil(NewStdObjectTestElement, &signature, kIterateForward);
if (i != kEmptyIndex)
return ((ObjClassID)((SignatureRecPtr)(gSignatures->ComputeAddress(i)))->itsClassID);
else
return kNilClass;
}
//--------------------------------------------------------------------------------------------------
#pragma segment MAOpen
pascal TObject* NewStdObject(IDType signature)
{
ObjClassID classID = GetClassIDFromSignature(signature);
if (classID != kNilClass)
return NewObjectByClassId(classID);
else
{
if (qDebug)
{
fprintf(stderr, "signature=‘%4s’\n", (char *) &signature);
ProgramBreak("Unable to find class for the given signature");
}
Failure(errMissingSignature, 0);
}
}
// old version is below
#if FALSE
pascal TObject* NewStdObject(IDType signature)
{
ArrayIndex i;
i = gSignatures->EachElementDoTil(NewStdObjectTestElement, &signature, kIterateForward);
if (i != kEmptyIndex)
return NewObjectByClassId((ObjClassID)((SignatureRecPtr)(gSignatures->ComputeAddress(i)))->itsClassID);
else
{
if (qDebug)
{
fprintf(stderr, "signature=‘%4s’\n", (char *) &signature);
ProgramBreak("Unable to find class for the given signature");
}
Failure((short) memFullErr, 0);
}
}
#endif
//--------------------------------------------------------------------------------------------------
#pragma segment MAOpen
pascal TObject* NewObjectBySignature(IDType signature,
const MAName& className)
{
if (className.IsEmpty())
{
return NewStdObject(signature);
}
else
{
return NewObjectByClassName(className);
}
}
//--------------------------------------------------------------------------------------------------
#pragma segment MAGlobalsRes
short FindPos(const Str255& pattern,
Str255& source)
{
short i = 0;
short j = 0;
short position = 0;
do
{
++i;
position = i;
for (j = 1; j <= pattern.Length(); ++j)
if (!((source[i + j - 1] == pattern[j]) && (CharByte((Ptr) & source, i + j) == 0)))
{
position = 0;
break;
}
} while (!((position > 0) || (i >= source.Length() - pattern.Length() + 1)));
return position;
}
pascal Boolean ParseTitleTemplate(Str255& itsTemplate,
short& preDocname,
short& constTitle)
{
const Str255 kPreDocname = "<<<";
const short kPreSize = 3;
const Str255 kPostDocname = ">>>";
const short kPostSize = 3;
if (itsTemplate.IsEmpty())
{
preDocname = 1;
constTitle = 0;
}
else
{
preDocname = FindPos(kPreDocname, itsTemplate);
if (preDocname > 0)
{
itsTemplate.Delete(preDocname, kPreSize);
short x = FindPos(kPostDocname, itsTemplate);
if (x == 0)
constTitle = preDocname - 1;
else
{
itsTemplate.Delete(x, kPostSize);
constTitle = itsTemplate.Length() - x + preDocname;
}
}
}
return preDocname > 0;
}
//--------------------------------------------------------------------------------------------------
#pragma segment MAGlobalsRes
pascal Boolean RegisterStdTypeTestElement(ArrayIndex elementIndex,
void* staticLink)
{
return (((SignatureRecPtr)(gSignatures->ComputeAddress(elementIndex)))->itsSignature == *((IDType *)staticLink));
}
pascal void RegisterStdType(const Str255& typeName,
IDType signature)
// Register or re-register a type and a class
{
ArrayIndex i;
SignatureRec itsSignatureRec;
// If the name can't be found it was probably misspelled or dead-stripped
itsSignatureRec.itsSignature = signature;
itsSignatureRec.itsClassID = GetClassIDFromName(typeName);
if (itsSignatureRec.itsClassID == kNilClass)
Failure(minErr, 0); //??? need to assign a message???
// Replace or add signature as necessary
i = gSignatures->EachElementDoTil(RegisterStdTypeTestElement, &signature, kIterateForward);
if (i != kEmptyIndex)
*((SignatureRecPtr)(gSignatures->ComputeAddress(i))) = itsSignatureRec;
else
gSignatures->InsertElementsBefore(gSignatures->GetSize() + 1, (Ptr) & itsSignatureRec, 1);
}
//--------------------------------------------------------------------------------------------------
#pragma segment MAGlobalsRes
pascal Boolean SubstituteInTitle(Str255& title,
const Str255& newStuff,
short preDocname,
short constTitle)
{
if (preDocname > 0)
{
if (constTitle == 0)
title = newStuff;
else
{
title.Delete(preDocname, title.Length() - constTitle);
title.Insert(newStuff, preDocname);
}
return TRUE;
}
else
return FALSE;
}
//--------------------------------------------------------------------------------------------------
#if qDebug
#pragma segment MADebug
/*$Push*/
#if qTrace
/*$D+*/
#endif
pascal void UseTempRgn(const Str255& byWhom)
/* Call this when you are about to use gTempRgn and qDebug is true. Used
with DoneWithTempRgn will prevent you from trying to use gTempRgn
from two places at the same time. */
{
if (gBusyTempRgn)
{
fprintf(stderr, "‘%s’ is trying to lock gTempRgn,", (char *) byWhom);
fprintf(stderr, "but it is already locked by ‘%s’\n", (char *) gUsedBy);
ProgramBreak("Error in UseTempRgn");
}
else
{
gBusyTempRgn = TRUE;
gUsedBy = byWhom;
}
}
//$Pop
#endif
//--------------------------------------------------------------------------------------------------
#if qDebug
#pragma segment MADebug
/*$Push*/
#if qTrace
/*$D+*/
#endif
pascal void UseTempRgn2(const Str255& byWhom)
/* Call this when you are about to use gTempRgn2 and qDebug is true. Used
with DoneWithTempRgn2 will prevent you from trying to use gTempRgn2
from two places at the same time. */
{
if (gBusyTempRgn2)
{
fprintf(stderr, "‘%s’ is trying to lock gTempRgn2,", (char *) byWhom);
fprintf(stderr, "but it is already locked by ‘%s’\n", (char *) gUsedBy);
ProgramBreak("Error in UseTempRgn2");
}
else
{
gBusyTempRgn2 = TRUE;
gUsedBy2 = byWhom;
}
}
//$Pop
#endif